package com.eucalyptus.binding; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.jibx.binding.Compile; public class BuildBindings extends Task { private List<FileSet> classFileSets = null; private List<FileSet> bindingFileSets = null; private List<String> bindings = null; @Override public void init( ) throws BuildException { super.init( ); this.classFileSets = new ArrayList<FileSet>( ); this.bindingFileSets = new ArrayList<FileSet>( ); this.bindings = new ArrayList<String>( ); } public void addClassFileSet( FileSet classFiles ) { this.classFileSets.add( classFiles ); } public void addBindingFileSet( FileSet bindings ) { this.bindingFileSets.add( bindings ); } private String[] paths( ) { Set<String> dirs = new HashSet<String>( ); for ( FileSet fs : this.classFileSets ) { final String dirName = fs.getDir( getProject( ) ).getAbsolutePath( ); for ( String d : fs.getDirectoryScanner( getProject( ) ).getIncludedFiles( ) ) { final String buildDir = dirName + File.separator + d.replaceAll( "build/.*", "build" ); if ( !dirs.contains( buildDir ) ) { log( "Found class directory: " + buildDir ); dirs.add( buildDir ); } } } return dirs.toArray( new String[] {} ); } private String[] bindings( ) { List<String> bindings = new ArrayList<String>( ); boolean addMsgs = true; for ( FileSet fs : this.bindingFileSets ) { final String dirName = fs.getDir( getProject( ) ).getAbsolutePath( ); for ( String b : fs.getDirectoryScanner( getProject( ) ).getIncludedFiles( ) ) { final String bindingFilePath = dirName + File.separator + b; log( "Found binding: " + bindingFilePath ); if( bindingFilePath.endsWith( "msgs-binding.xml" ) ) { addMsgs = false; } bindings.add( bindingFilePath ); } } if( addMsgs ) { bindings.add( "modules/msgs/src/main/resources/msgs-binding.xml" ); } return bindings.toArray( new String[] {} ); } PrintStream oldOut = System.out, oldErr = System.err; public void error( Throwable e ) { e.printStackTrace( System.err ); System.setOut( oldOut ); System.setErr( oldErr ); e.printStackTrace( System.err ); log( e.getMessage( ) ); System.exit( -1 ); } public void execute( ) { PrintStream buildLog; try { buildLog = new PrintStream( new FileOutputStream( "bind.log", false ) ); System.setOut( buildLog ); System.setErr( buildLog ); } catch ( FileNotFoundException e2 ) { System.setOut( oldOut ); System.setErr( oldErr ); } if ( this.classFileSets.isEmpty( ) ) { throw new BuildException( "No classes were provided to bind." ); } else if ( this.bindingFileSets.isEmpty( ) ) { throw new BuildException( "No bindings were provided to bind." ); } else { try { System.setProperty( "java.class.path", ( ( AntClassLoader ) BuildBindings.class.getClassLoader( ) ).getClasspath( ) ); } catch ( Exception e ) { System.err.println( "Failed setting classpath from Ant task" ); } Path path = new Path( getProject( ) ); for( String p : paths( ) ) { path.add( new Path( getProject( ), p ) ); } for( File f : new File( "lib" ).listFiles( new FilenameFilter() { @Override public boolean accept( File dir, String name ) { return name.endsWith( ".jar" ); }} ) ) { path.add( new Path( getProject( ), f.getAbsolutePath( ) ) ); } ClassLoader old = Thread.currentThread( ).getContextClassLoader( ); List<BindingGenerator> generators = BindingGenerator.getGenerators(); try { AntClassLoader loader = this.getProject( ).createClassLoader( path ); Thread.currentThread( ).setContextClassLoader( loader ); // System.err.print( "class path: " + loader.getClasspath( ) ); BindingGenerator.MSG_TYPE = loader.forceLoadClass( "edu.ucsb.eucalyptus.msgs.BaseMessage" ); BindingGenerator.DATA_TYPE = loader.forceLoadClass( "edu.ucsb.eucalyptus.msgs.EucalyptusData" ); loader.forceLoadClass( "org.jibx.binding.model.JiBX_bindingFactory" ); for ( FileSet fs : this.classFileSets ) { for ( String classFileName : fs.getDirectoryScanner( getProject( ) ).getIncludedFiles( ) ) { try { if( !classFileName.endsWith( "class" ) ) continue; Class c = loader.forceLoadClass( classFileName.replaceFirst( "[^/]*/[^/]*/", "" ).replaceAll( "/", "." ).replaceAll( "\\.class.{0,1}", "" ) ); if ( BindingGenerator.MSG_TYPE.isAssignableFrom( c ) || BindingGenerator.DATA_TYPE.isAssignableFrom( c ) ) { for( BindingGenerator gen : generators ) { gen.processClass( c ); } } } catch ( ClassNotFoundException e ) { error( e ); } } } } catch ( ClassNotFoundException e1 ) { error( e1 ); } finally { try { for( BindingGenerator gen : generators ) { gen.close( ); } } catch ( Throwable e ) { error( e ); } Thread.currentThread( ).setContextClassLoader( old ); } try { Compile compiler = new Compile( true, true, false, false, false ); compiler.compile( paths( ), bindings() ); } catch ( Throwable e ) { error( e ); } finally { System.setOut( oldOut ); System.setErr( oldErr ); } } } }